<?php


namespace App\Service\OpenShop\Feishu;

use App\Exceptions\Custom\CustomHttpResponseException;
use App\Http\Middleware\OpenShop\UserPermissionAuth;
use App\Jobs\OpenShop\ChangeManagerJob;
use App\Jobs\OpenShop\PayCsv;
use App\Library\Rms\RmsShopApi;
use App\Models\BaseModel;
use App\Models\OpenShop\Common\OpenShopOrderManagerModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopAddressModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationManageUserModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationRegionMappingModel;
use App\Models\Shop\ShopModel;
use App\Service\OpenShop\OrderService;
use App\Service\OpenShop\User\RmsUserService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class OrganizationManageUserService extends BaseService
{
    public static function addUser(
        int $manageId,
        int $type,
        array $cityManagers,
        array $relationProvinceCodes = [],
        int $currentUid = 0,
        int $isReplace = 0
    ) {
        /*
        {
        "cityManagers":[
                {
                    "userId":6,
                    "addressCodesArr":[
                        {
                            "provinceCode":"310000",
                            "cityCode":"311000"
                            "regionCode": 111111 // 可以为空，或不存在
                        }
                    ]
                }
            ]
        }
        */

        // 自动填充 - 负责区域
        if (!$relationProvinceCodes) {
            $relationProvinceCodes = OpenShopOrganizationRegionMappingModel::query()
                                                                           ->where('manageId', $manageId)
                                                                           ->pluck('provinceCode')
                                                                           ->toArray();
        }

        $delUserIds     = [];// 被删除督导用户数据

        // 区域校验
        if ($cityManagers) {
            if ($type == OpenShopOrganizationManageUserModel::TYPE_INCREASE_MANAGER) {// 督导目前直接关联门店了 需要后端查询门店对应区域
                foreach ($cityManagers as &$cityManager) {
                    $shopIds         = $cityManager['shopIds'] ?? [];
                    $addressCodesArr = [];
                    if ($shopIds) {
                        if (!$isReplace) {// 不替换时 剔除门店
                            $checkShopData = OpenShopOrderManagerModel::getNotRelShopIdByUid($shopIds, [$cityManager['userId']]);
                            if ($checkShopData) {
                                $delShopIds             = array_column($checkShopData, 'shopId');
                                $cityManager['shopIds'] = array_diff($shopIds, $delShopIds);
                            }
                        }
                        $addressCodesArr = ShopModel::getShopInfosByParams($shopIds, 'province provinceCode,city cityCode,district regionCode');
                    } else {
                        $delUserIds[] = $cityManager['userId'];
                    }
                    $cityManager['addressCodesArr'] = $addressCodesArr;
                }
            }
            if ($type != OpenShopOrganizationManageUserModel::TYPE_INCREASE_MANAGER) {// 督导不判断负责区域
                foreach ($cityManagers as $val) {
                    foreach ($val['addressCodesArr'] as $v) {
                        if (!in_array($v['provinceCode'], $relationProvinceCodes)) {
                            \App\Service\BaseService::throwErr('负责区域，不能超出服务区域的范围');
                        }
                    }
                }
            }

            $userIds   = array_column($cityManagers, 'userId');
            $userInfos = collect(RmsUserService::getRmsUserInfoByUserIds($userIds)['data'])->keyBy('id');
        } else {
            $userIds = $userInfos = [];
        }

        // 校验区域归属人变化
        $diffManagers = [];
        //        $diffManagers = self::diffManager($type, $manageId, $cityManagers);

        $userMapShopIds = [];// 督导用户关联门店id

        DB::beginTransaction();

        // 删除不存在的记录
        if ($type == OpenShopOrganizationManageUserModel::TYPE_INCREASE_MANAGER) {
            if ($delUserIds) {
                OpenShopOrganizationManageUserModel::query()
                    ->where('manageId', $manageId)
                    ->where('type', $type)
                    ->whereIn('userId', $delUserIds)
                    ->delete();
            }
        } else {
            OpenShopOrganizationManageUserModel::query()
                ->where('manageId', $manageId)
                ->where('type', $type)
                ->when(
                    $userIds, function ($query) use ($userIds) {
                    $query->whereNotIn('userId', $userIds);

                }
                )
                ->delete();
        }

        foreach ($cityManagers as $item) {
            $shopIds = $item['shopIds'] ?? [];

            $userMapShopIds[] = [
                'userId'  => $item['userId'],
                'shopIds' => $shopIds,
            ];
            if (!$shopIds && $type == OpenShopOrganizationManageUserModel::TYPE_INCREASE_MANAGER) {// 督导没有门店关联时视为删除
                continue;
            }

            $addressCodes = [];
            foreach ($item['addressCodesArr'] ?? [] as $v) {
                $provinceCode = $v['provinceCode'] ?? '';
                $cityCode     = $v['cityCode'] ?? '';
                $regionCode   = $v['regionCode'] ?? '';

                $addressCodes[] = $provinceCode . '-' . $cityCode . '-' . $regionCode;
            }

            OpenShopOrganizationManageUserModel::query()->updateOrCreate([
                'manageId' => $manageId,
                'type'     => $type,
                'userId'   => $item['userId']
            ], ['name' => $userInfos[$item['userId']]['username'] ?? '', 'addressCodes' => json_encode($addressCodes)]);
        }

        DB::commit();

        Log::info("ChangeManager Queue diff...", ['diffManagers' => $diffManagers, 'userMapShopIds' => $userMapShopIds]);

        // 督导更换 - queue
        /*if ($userMapShopIds && $type == OpenShopOrganizationManageUserModel::TYPE_INCREASE_MANAGER) {
            dispatch((new ChangeManagerJob($type, [], $currentUid, $userMapShopIds, $delUserIds)))->onQueue('{change-managers}');
        }*/
    }

    // 校验区域归属人变化
    private static function diffManager(int $type, int $manageId, array $cityManagers): array
    {
        if ($type == OpenShopOrganizationManageUserModel::TYPE_INCREASE_MANAGER) {
            $originalMappings = [];
            OpenShopOrganizationManageUserModel::query()
                                               ->where('manageId', $manageId)
                                               ->where('type', $type)
                                               ->get()
                                               ->each(function ($item) use (&$originalMappings) {
                                                   if (!$item->addressCodesArr) {
                                                       return;
                                                   }
                                                   foreach ($item->addressCodesArr as $v) {
                                                       $originalMappings[] = "{$item['userId']}-{$v['provinceCode']}-{$v['cityCode']}-{$v['regionCode']}";
                                                   }

                                               });


            $newMappings = [];
            foreach ($cityManagers as $manager) {
                foreach ($manager['addressCodesArr'] as $v) {
                    $newMappings[] = "{$manager['userId']}-{$v['provinceCode']}-{$v['cityCode']}-{$v['regionCode']}";
                }
            }

            return [
                'type'    => $type,
                'address' => collect(array_diff($newMappings, $originalMappings))
                    ->map(function ($item) use ($type) {
                        $itemArr = explode('-', $item);

                        return [
                            'targetUid'       => $itemArr[0],
                            'provinceCode' => $itemArr[1],
                            'cityCode'     => $itemArr[2],
                            'regionCode'   => $itemArr[3],
                        ];
                    })->toArray(),
            ];

        }

        return [];
    }

    /**
     * 查询门店的稽核负责人
     * @param int $shopId
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function getCruiseCheckManager(int $shopId): array
    {
        $shops = (new RmsShopApi())->getShopByIds([$shopId])['data']['shopList'][0] ?? [];
        if (!$shops) {
            return [];
        }

        $addressCode = $shops['province'] . '-' . $shops['city'] . '-' . $shops['district'];

        $model = OpenShopOrganizationManageUserModel::query()
                                                    ->where('type',
                                                        OpenShopOrganizationManageUserModel::TYPE_CHECK_MANAGER)
                                                    ->where('addressCodes', 'like', "%{$addressCode}%")
                                                    ->select('userId')
                                                    ->orderByDesc('id')
                                                    ->first();
        if (!$model) {
            return [];
        }

        $user = RmsUserService::getRmsUserInfoByUserIds([$model->userId])['data'][0] ?? [];

        return [
            'userId' => $model->userId,
            'name'   => $user['username'] ?? '',
            'mobile' => $user['mobile'] ?? '',
        ];
    }

    /**
     * 省区开发添加
     * @param int $manageId
     * @param int $rmsUserId
     * @param array $data
     * @return array
     */
    public static function provinceDevelopmentUser(int $manageId, int $rmsUserId, array $data): array
    {
        if (!empty($data)) {

            $developmentUserQuery = OpenShopOrganizationManageUserModel::query()
                ->withoutGlobalScope('isDel')
                ->where('manageId', $manageId)
                ->where(
                    'type',
                    OpenShopOrganizationManageUserModel::TYPE_SITE_SELECTION_DEVELOPMENT
                );

            $existsDevelopmentUser = (clone $developmentUserQuery)->get();
            (clone $developmentUserQuery)->update(
                [
                    'isDeleted'    => 1,
                    'updatedAt'    => time(),
                    'updatedByUid' => $rmsUserId
                ]
            );

            $normalUidGroup = array_intersect(
                array_column($data, 'uid'),
                $existsDevelopmentUser->pluck('userId')->toArray()
            );
            if ($normalUidGroup) {
                //已存在数据置为正常
                (clone $developmentUserQuery)->whereIn('userId', $normalUidGroup)->update(
                    [
                        'addressCodes' => null,
                        'isDeleted'    => 0,
                        'updatedAt'    => time(),
                        'updatedByUid' => $rmsUserId
                    ]
                );
            }

            $notExistsUidGroup = array_diff(array_column($data, 'uid'), $normalUidGroup);
            if ($notExistsUidGroup) {
                //不存在数据新增记录
                OpenShopOrganizationManageUserModel::query()->insert(
                    collect($data)->whereIn('uid', $notExistsUidGroup)->map(
                        function (
                            $developmentUser
                        ) use ($rmsUserId, $manageId) {
                            return [
                                'manageId'     => $manageId,
                                'name'         => $developmentUser['name'],
                                'type'         => OpenShopOrganizationManageUserModel::TYPE_SITE_SELECTION_DEVELOPMENT,
                                'userId'       => $developmentUser['uid'],
                                'createdByUid' => $rmsUserId,
                                'updatedByUid' => $rmsUserId,
                                'createdAt'    => time(),
                                'updatedAt'    => time()
                            ];
                        }
                    )->values()->toArray()
                );
            }
        }
        return [];
    }

    /**
     * 通过省市区code匹配对应区域的人员，当前区域只有一个督导时返回数据，否则返回空
     * @param int $type
     * @param string $provinceCode
     * @param string $cityCode
     * @param string $areaCode
     * @return array
     */
    public static function getManagerByAddressCodes(int $type, string $provinceCode, string $cityCode, string $areaCode = ''): array
    {
        $addressCodes = (string)($provinceCode . '-' . $cityCode . '-' . $areaCode);

        $res = OpenShopOrganizationManageUserModel::query()
            ->where('type', $type)
            ->whereRaw("JSON_CONTAINS(addressCodes, JSON_ARRAY('{$addressCodes}'))")
            ->select(['userId', 'name'])
            ->get()
            ->toArray();
        if (count($res) == 1) {
            return $res[0] ?? [];
        } else {
            return [];
        }
    }

    /**
     * 督导修改优化同步处理
     * @param int $manageId
     * @param int $type
     * @param array $cityManagers
     * @param array $relationProvinceCodes
     * @param int $currentUid
     * @param int $isReplace
     * @param int $oldUserId
     */
    public static function changeManager(
        int $manageId,
        int $type,
        array $cityManagers,
        array $relationProvinceCodes = [],
        int $currentUid = 0,
        int $isReplace = 0,
        int $oldUserId = 0
    )
    {

        // 负责区域
        $relationProvinceCodes = OpenShopOrganizationRegionMappingModel::query()
            ->where('manageId', $manageId)
            ->pluck('provinceCode')
            ->toArray();

        $childOrderNo = OpenShopAddressModel::query()
        ->whereIn('provinceCode', $relationProvinceCodes)
        ->select('orderNo');

        // 根据负责区域查询对应订单
        $childMainProcessIds = OpenShopMainProcessModel::query()
            ->whereRaw('orderNo in (' . BaseModel::toSqlWithParam($childOrderNo) . ')')
            ->select('id');

        $delUserIds        = [];// 被删除督导用户数据
        $delMainProcessIds = [];// 被删除督导用户数据关联订单数据

        $userMapShopIds = [];// 督导用户关联门店id

        foreach ($cityManagers as $k => $cityManager) {
            $shopIds = $cityManager['shopIds'] ?? [];
            if ($shopIds) {
                if (!$isReplace) {// 不替换时 剔除门店
                    $checkShopData = OpenShopOrderManagerModel::getNotRelShopIdByUid($shopIds, [$cityManager['userId']]);
                    if ($checkShopData) {
                        $delShopIds                  = array_column($checkShopData, 'shopId');
                        $cityManagers[$k]['shopIds'] = array_diff($shopIds, $delShopIds);
                    }
                }
                $cityManagers[$k]['addressCodes'] = ShopModel::getShopInfosByParams($shopIds, 'province,city,district');

                if ($oldUserId) {
                    $delUserIds[] = $oldUserId;// 替换督导时传之前的 督导id
                }
            } else {
                $delUserIds[] = $cityManager['userId'];

                $delMainProcessIds = OpenShopOrderManagerModel::query()
                    ->whereRaw('mainProcessId in (' . BaseModel::toSqlWithParam($childMainProcessIds) . ')')
                    ->whereIn('managerUid', $delUserIds)
                    ->where('type', OpenShopOrderManagerModel::MANAGER_TYPE_5)            // 督导
                    ->where('orderStatus', OpenShopOrderManagerModel::ORDER_STATUS_NORMAL)// 正常
                    ->pluck('mainProcessId')->toArray();
            }
        }

        foreach ($cityManagers as $val) {
            if (isset($val['addressCodes']) && $val['addressCodes']) {
                foreach ($val['addressCodes'] as $v) {
                    $addressCodes = explode('-', $v);
                    $provinceCode = $addressCodes[0] ?? 0;
                    if (!in_array($provinceCode, $relationProvinceCodes)) {
                        \App\Service\BaseService::throwErr('负责区域，不能超出服务区域的范围');
                    }
                }
            }
        }

        $userIds   = array_column($cityManagers, 'userId');
        $userInfos = collect(RmsUserService::getRmsUserInfoByUserIds($userIds)['data'])->keyBy('id');


        // 开店 - 组织管理-用户mappings
        DB::beginTransaction();

        try {

            // 删除不存在的记录
            if ($delUserIds) {
                OpenShopOrganizationManageUserModel::query()
                    ->where('manageId', $manageId)
                    ->where('type', $type)
                    ->whereIn('userId', $delUserIds)
                    ->delete();
            }

            foreach ($cityManagers as $item) {
                $shopIds = $item['shopIds'] ?? [];
                if (!$shopIds) {// 督导没有门店关联时视为删除
                    continue;
                }

                OpenShopOrganizationManageUserModel::query()->updateOrCreate(
                    [
                        'manageId' => $manageId,
                        'type'     => $type,
                        'userId'   => $item['userId']
                    ],
                    ['name' => $userInfos[$item['userId']]['username'] ?? '', 'addressCodes' => json_encode($item['addressCodes'])]
                );

                // 门店对应订单
                $mainProcessIds = OpenShopMainProcessModel::query()
                    ->whereRaw('id in (' . BaseModel::toSqlWithParam($childMainProcessIds) . ')')
                    ->whereIn('shopId', $shopIds)->pluck('id');

                // 督导未关联的门店 更换督导
                $getMainProcessIds = OpenShopOrderManagerModel::query()
                    ->whereIn('mainProcessId', $mainProcessIds)
                    ->whereNotIn('managerUid', [$item['userId']])
                    ->where('type', OpenShopOrderManagerModel::MANAGER_TYPE_5)            // 督导
                    ->where('orderStatus', OpenShopOrderManagerModel::ORDER_STATUS_NORMAL)// 正常
                    ->pluck('mainProcessId')->toArray();

                $userMapShopIds[] = [
                    'userId'         => $item['userId'],
                    'shopIds'        => $shopIds,
                    'mainProcessIds' => $getMainProcessIds,
                ];

                // 查询督导之前关联的门店 删除督导
                $getDelMainProcessIds = OpenShopOrderManagerModel::query()
                    ->where('managerUid', $item['userId'])
                    ->whereRaw('mainProcessId in (' . BaseModel::toSqlWithParam($childMainProcessIds) . ')')
                    ->whereNotIn('mainProcessId', $mainProcessIds)
                    ->where('type', OpenShopOrderManagerModel::MANAGER_TYPE_5)            // 督导
                    ->where('orderStatus', OpenShopOrderManagerModel::ORDER_STATUS_NORMAL)// 正常
                    ->pluck('mainProcessId')->toArray();

                if ($getDelMainProcessIds) {
                    $delMainProcessIds = array_unique(array_merge($delMainProcessIds, $getDelMainProcessIds));
                }
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            Log::info(
                'ChangeManagerUsersErr', [
                    'manageId'          => $manageId,
                    'userIds'           => $userIds,
                    'cityManagers'      => $cityManagers,
                    'userMapShopIds'    => $userMapShopIds,
                    'delUserIds'        => $delUserIds,
                    'delMainProcessIds' => $delMainProcessIds,
                ]
            );

            throw new CustomHttpResponseException('修改manageUsers失败', $e);
        }

        Log::info('ChangeManager ', ['userMapShopIds' => $userMapShopIds, 'delMainProcessIds' => $delMainProcessIds]);

        // 同步督导更换
        self::syncChangeManager($currentUid, $userMapShopIds, $delMainProcessIds);
    }

    /**
     * 同步督导更换
     * @param int $operateUid
     * @param array $userMapShopIds
     * @param array $delMainProcessIds
     * @return array
     */
    public static function syncChangeManager(int $operateUid, array $userMapShopIds, array $delMainProcessIds): array
    {
        $totalNum       = 0;
        $mainProcessIds = [];

        $userIds  = array_column($userMapShopIds, 'userId');
        $getUsers = collect(RmsUserService::getRmsUserInfoByUserIds(array_merge($userIds, [$operateUid]), [], true)['data'] ?? [])->keyBy('id')->toArray();

        $operateUserName     = $getUsers[$operateUid]['username'] ?? '';
        $operateUserFeishuId = $getUsers[$operateUid]['feishuUserId'] ?? '';

        // 根据门店id关联督导
        if ($userMapShopIds) {
            foreach ($userMapShopIds as $v) {

                $targetUid      = $v['userId'];
                $targetUserName = $getUsers[$v['userId']]['username'] ?? '';

                // 更换督导
                $res = self::syncChangeManagerByMainProcessIds($v['mainProcessIds'], $operateUid, $operateUserName, $targetUid, $targetUserName);
                if ($res['totalNum']) {
                    $totalNum += $res['totalNum'];
                }
                if ($res['mainProcessIds']) {
                    $mainProcessIds = array_merge($mainProcessIds, $res['mainProcessIds']);
                }
            }
        }

        // 被删除督导用户数据
        if ($delMainProcessIds) {

            // 删除督导
            $res = self::syncChangeManagerByMainProcessIds($delMainProcessIds, $operateUid, $operateUserName);
            if ($res['totalNum']) {
                $totalNum += $res['totalNum'];
            }
            if ($res['mainProcessIds']) {
                $mainProcessIds = array_merge($mainProcessIds, $res['mainProcessIds']);
            }
        }

        // 飞书通知
        $orderNoStr = OpenShopMainProcessModel::query()->whereIn('id', $mainProcessIds)->pluck('orderNo')->implode('\n');

        // 简单飞书推送，督导更换完毕
        $templateJson = vsprintf(file_get_contents(resource_path('OpenShop/feishu/notifyTemplate/changeManager.json')), ['营运', $totalNum, $operateUserName, $orderNoStr]);

        MessageSendService::sendMessage($operateUserFeishuId, 'user_id', json_decode($templateJson, true), 'interactive', UserPermissionAuth::MODULE_OPEN_SHOP);

        return [];
    }

    public static function syncChangeManagerByMainProcessIds(array $searchMainProcessIds, int $operateUid, string $operateUserName, int $managerId = 0, string $managerName = ''): array
    {
        $totalNum       = 0;
        $mainProcessIds = [];
        OpenShopOrderManagerModel::query()
            ->whereIn('mainProcessId', $searchMainProcessIds)
            ->where('type', OpenShopOrderManagerModel::MANAGER_TYPE_5)
            ->get()
            ->each(
                function ($item) use ($managerId, $managerName, $operateUid, &$totalNum, &$mainProcessIds, $operateUserName) {
                    $userInfo     = (object)[
                        'id'       => $operateUid,
                        'username' => $operateUserName,
                    ];
                    $paramsFormat = (object)[
                        'id'          => $item->id,
                        'type'        => $item->type,
                        'managerId'   => $managerId,
                        'managerName' => $managerName,
                    ];

                    Log::info("syncChangeManager start... targetUid:0 operateUid:{$operateUid} id:{$item->id}");

                    try {
                        $do = OrderService::changeManager($userInfo, $paramsFormat);
                        if ($do) {
                            $totalNum++;
                            $mainProcessIds[] = $item->mainProcessId;
                        }
                    } catch (\Exception $e) {
                        Log::warning("syncChangeManager Err ...id:{$item->id}", ['msg' => $e->getMessage()]);
                    }

                    Log::info("syncChangeManager end...id:{$item->id}");
                }
            );

        return [
            'totalNum'       => $totalNum,
            'mainProcessIds' => $mainProcessIds,
        ];
    }

}
